package com.ideal.frame.application.service;

import cn.hutool.core.date.DateTime;
import cn.hutool.core.lang.UUID;
import com.ideal.frame.application.entity.Application;
import com.ideal.frame.application.entity.ApplicationSecret;
import com.ideal.frame.application.entity.dto.OrgDto;
import com.ideal.frame.application.form.AppSearchForm;
import com.ideal.frame.application.form.AppSecretSearchForm;
import com.ideal.frame.application.repository.ApplicationRepository;
import com.ideal.frame.application.repository.ApplicationUserRepository;
import com.ideal.frame.institutions.entity.InstitutionsOrganizationTb;
import com.ideal.frame.institutions.entity.QInstitutionsOrganizationTb;
import com.ideal.frame.jpa.JpaRepositoryImpl;
import com.querydsl.core.types.Projections;
import com.querydsl.jpa.impl.JPAQuery;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.PostConstruct;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import java.util.ArrayList;
import java.util.List;

/**
 * @Author ybb
 * @Description
 * @Date 2021/8/24 17:28
 */
@Service
@Transactional
@Slf4j
public class ApplicationService {

    @Autowired
    ApplicationRepository repository;
    @Autowired
    ApplicationUserRepository userRepository;


    @PersistenceContext
    protected EntityManager entityManager;
    private JpaRepositoryImpl<InstitutionsOrganizationTb, String> ioRepo;

    QInstitutionsOrganizationTb qInstitutionsOrganizationTb = QInstitutionsOrganizationTb.institutionsOrganizationTb;

    @PostConstruct
    public void initRepo() {
        ioRepo = new JpaRepositoryImpl<>(InstitutionsOrganizationTb.class, entityManager);
    }



    public Page<Application> pages(AppSearchForm searchForm){
        Specification<Application> specification = new Specification<Application>() {
            @Override
            public Predicate toPredicate(Root<Application> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder cb) {
                List<Predicate> predicates = new ArrayList<>();
                if (StringUtils.isNoneBlank(searchForm.getAppName())){
                    predicates.add(cb.equal(root.get("appName"),searchForm.getAppName()));
                }
                if (searchForm.getAppType() >0){
                    predicates.add(cb.equal(root.get("appType"),searchForm.getAppType()));
                }
                return cb.and(predicates.toArray(new Predicate[predicates.size()]));
            }

        };
        return repository.findAll(specification,PageRequest.of(searchForm.getPageNo()-1,searchForm.getPageSize()));
    }

    public Page<ApplicationSecret> secretPages(AppSecretSearchForm secretSearchForm){
        Specification<ApplicationSecret> specification = new Specification<ApplicationSecret>(){
            @Override
            public Predicate toPredicate(Root<ApplicationSecret> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder cb) {
                List<Predicate> predicates = new ArrayList<>();
                predicates.add(cb.equal(root.get("applicationId"),secretSearchForm.getApplicationId()));
                return cb.and(predicates.toArray(new Predicate[predicates.size()]));
            }
        };
        return userRepository.findAll(specification,PageRequest.of(secretSearchForm.getPageNo()-1,secretSearchForm.getPageSize()));
    }

    public Application getOne(long id){
        return repository.findById(id).get();
    }

    public void add(Application application){
//        application.setAppKey(uniqueKey());
        repository.save(application);
    }

    @Transactional
    public void del( List<Long> ids){
        ids.forEach(id -> {
            Application application = repository.getOne(id);
            int count = userRepository.deleteSecret(application.getAppKey());
            log.info("删除应用密钥 -> key={},count={}",application.getAppKey(),count);
            repository.deleteById(id);
        });

    }

    public void update(Application application){
        repository.save(application);
    }

    public void addAppSecret(ApplicationSecret appUser){
        appUser.setUpdateDate(new DateTime());
        userRepository.save(appUser);
    }

    public void delAppSecret( List<Long> ids){
        ids.forEach(id -> {
            userRepository.deleteById(id);
        });
    }




    //获取机构列表
    public List<OrgDto> getOrgs(){
        JPAQuery jpaQuery =  ioRepo.select(
                Projections.bean(OrgDto.class,
                        qInstitutionsOrganizationTb.gnrlid,
                        qInstitutionsOrganizationTb.orgname))
                .from(qInstitutionsOrganizationTb)
                .where(qInstitutionsOrganizationTb.delFlag.eq(Boolean.FALSE));
        return jpaQuery.fetchResults().getResults();
    }

    /*
     待定
     */
    public String uniqueKey(){
        return UUID.randomUUID().toString().replaceAll("-","").toUpperCase();
    }
}
